Java Exception Policy

Did you ever encountered projects where low-level functions launched different sorts of Java exceptions so that any high-level method threw Exception? I did. Not only the treatment of errors was kind of a guesswork, but I also thought it pretty much killed the principle of having a distinction between Exception and RuntimeException.

At that time, i just had discovered the principle of fail-fast when attempting to modify a list i was reading. It struck me that, in the context of small, exploratory, student project software, it was often more efficient to let the program crash instead of trying to recover from the error.

From that, I came up with the following guidelines:
  • If a failure is a normal outcome, use special return values. Example: there is no solution to the equation given to the symbolic solver class, return a NaN or a null. Even better, return a pair ["error", "description of the error"] instead of the normal ["ok", 42]. However this is not always practical in java.
  • Only throw normal exceptions you want to deal with at the level right above: they will be meaningless at higher levels.
  • Throw RuntimeExceptions when there is an obvious programmer error: just slap your teammate in the face with a good exception when he's too lazy to glance at the sentence "x >= 0" you wrote in the documentation. Besides, it will help yourself to debug during those project sprints when you don't remember anymore how you wrote this class three months ago.
  • Throw RuntimeExceptions when there are errors you don't want to bother with, at least when the project is small. That is, you know your file exists, is readable/writable because you dealt with the FileNotFoundException and the IOException on the opening of the file, but you are reading it further in your code. In my humble opinion, if the user disconnects his external drive while you read a file on it, he can as well go fuck himself.
This should be coupled with the declaration of the RuntimeExceptions a function manually throws, so that if the level right above really wants to deal with it, it can, and don't have to fight ghosts.

Crashing a program on error might be shocking. However, failing like this is better for the overall reliability of the system: bugs are detected faster and a module does not try to continue operation in a messed up state. This also allows the module to fail and be restarted if the system has to be highly fault-tolerant.